<?php
// 应用公共文件

//require_once WWW.DS.'app'.DS.'install'.DS.'common.php';


/**
 * 文件域名追加
 * $arr         array   数据
 * $data        array   参数
 *                      type        int         http追加样式
 *                      val         int         富文本内容域名追加，正则样式（null：直接追加，1：/地址的样式进行追加）
 *                      httpurl     string      自定义追加的域名（默认自动获取服务器域名）
 *                      keyname     array       一维数组中的值为普通追加域名的字段,二维数组中的值为富文本字段；采用索引数组
 *
 *  PHP版本不同可能有些语法不支持，请自行调整
 *
 * 更多样式自行添加开发
 */
if (!function_exists('urladd')) {
    function urladd(&$arr, $data = [])
    {
        //域名$_SERVER['SERVER_NAME']
        //http还是https,$_SERVER['REQUEST_SCHEME']
        if (empty($arr)) return $arr;
        if(isset($data['keyname'])){
            if (!is_array($data['keyname'])) unset($data['keyname']);
        }
        if(isset($data['type'])){
            $type = $data['type'];
        }else{
            $type = 1;
        }
        if(isset($data['val'])){
            $val = $data['val'];
        }else{
            $val = null;
        }
        if(isset($data['httpurl'])){
            $httpurl = $data['httpurl'];
        }else{
            $httpurl = null;
        }
        if(isset($data['keyname'])){
            $keyname = $data['keyname'];
        }else{
            $keyname = ['img', 'image','images', 'video', 'file'];
        }
        $keyarray = ['images'];
        if (!$httpurl) {
            if ($type == 1) {
                $url = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_NAME'];
            } elseif ($type == 2) {
                $url = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_NAME'] . '/';
            } else {
                $url = $_SERVER['HTTP_HOST'];
            }
        } else {
            $url = $httpurl;
        }
        if(is_object($arr)){
            $arr = $arr->toArray();
        }
        if(isset($arr[0])){
            foreach ($arr as $k=>$v){
                if(is_array($v)){
                    urladd($arr[$k]);
                }
                foreach ($keyname as $kk=>$vv){
                    if(urlif($v,$vv)){
                        if(strstr($v[$vv],',')){
                            $v[$vv] = explode(',',$v[$vv]);
                            foreach ($v[$vv] as $kkk=>$vvv){
                                if(!strstr($vvv,'http')){
                                    $v[$vv][$kkk] = $url . $vvv;
                                }
                            }
                            $arr[$k][$vv] = $v[$vv];
                        }elseif(!empty($v[$vv]) && !strstr($v[$vv],'http')){
                            $arr[$k][$vv] = $url . $v[$vv];
                        }
                    }elseif(isset($v[$vv]) && !empty($v[$vv]) && is_string($v[$vv]) && strstr($v[$vv],',')){
                        $v[$vv] = explode(',',$v[$vv]);
                        foreach ($v[$vv] as $kkk=>$vvv){
                            if(!strstr($vvv,'http')){
                                $v[$vv][$kkk] = $url . $vvv;
                            }
                        }
                        $arr[$k][$vv] = $v[$vv];
                    }
                }
                foreach ($keyarray as $kk=>$vv){
                    if(is_string($arr[$k][$vv]) && !empty($arr[$k][$vv])){
                        $arr[$k][$vv] = explode(',',$arr[$k][$vv]);
                    }
                }
            }
        }elseif(is_array($arr)){
            foreach ($arr as $k=>$v){
                if(is_array($v)){
                    urladd($arr[$k]);
                }
                foreach ($keyname as $kk=>$vv){
                    if(urlif($arr,$vv)){
                        if(strstr($arr[$vv],',')){
                            $arr[$vv] = explode(',',$arr[$vv]);
                            foreach ($arr[$vv] as $kkk=>$vvv){
                                if(!empty($vvv) && !strstr($vvv,'http')){
                                    $arr[$vv][$kkk] = $url . $vvv;
                                }
                            }
                        }elseif(!empty($arr[$vv]) && !strstr($arr[$vv],'http')){
                            $arr[$vv] = $url . $arr[$vv];
                        }
                    }elseif(isset($arr[$vv]) && !empty($arr[$vv]) && is_string($arr[$vv]) && strstr($arr[$vv],',')){
                        $arr[$vv] = explode(',',$arr[$vv]);
                        foreach ($arr[$vv] as $kkk=>$vvv){
                            if(!strstr($vvv,'http')){
                                $arr[$vv][$kkk] = $url . $vvv;
                            }
                        }
                    }
                }
                foreach ($keyarray as $kk=>$vv){
                    if($k == $vv && is_string($arr[$k]) && !empty($arr[$k])){
                        $arr[$k] = explode(',',$arr[$k]);
                    }
                }
            }

        }elseif(is_string($arr)){
            if(!empty($arr) && !strstr($arr,'http') && !strstr($arr,',')){
                $arr = $url . $arr;
            }elseif(!empty($arr) && !strstr($arr,'http')){
                $arr = explode(',',$arr);
                foreach ($arr as $k=>$v){
                    if(!strstr($v,'http')){
                        $arr[$k] = $url . $v;
                    }
                }
            }
        }
        return $arr;
    }
}

if (!function_exists('passWordDecrypt')) {
    function passWordDecrypt($password)
    {
        return md5(md5($password) . 'YSH' . base64_encode(724));
    }
}
/**
 * 文件域名追加
 * $arr         arr     数据
 * $httpurl     string  自定义的追加域名
 * 更多样式自行添加开发
 */
if (!function_exists('urlupdete')) {
    function urlupdete($arr, $httpurl = '')
    {
        return urladd($arr, $type = 2, $val = 0, $httpurl);
    }
}
/**
 * 数据字段判断
 * $arr    array|string   数据
 * $str    string         检索的字段名称
 * $type   int            样式(0:默认格式检查有没http，1：富文本字段检查使用)
 */
if (!function_exists('urlif')) {
    function urlif($arr, $str, $type = 0, $value = 'http')
    {
        if(is_string($arr)) return true;
        if(!is_array($arr)) return false;
        if ($type) {
            if (isset($arr[$str]) && !empty($arr[$str])) {
                return true;
            } else {
                return false;
            }
        } else {
            if (isset($arr[$str]) && !empty($arr[$str]) && !strpos($arr[$str], $value)) {
                return true;
            } else {
                return false;
            }
        }

    }
}
/**
 * 阿里云短信 发送，
 *
 * @param string  $phone        接收短信的电话号码
 * @param string  $code         短信模板code（平台配置的）
 * @param array   $temParam     短信模板中变量的值
 * @param string  $signname     短信的签名名称（平台配置的）
 *
 */
//阿里云短信 引用类文件
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
if(!file_exists('ali_send_msg')){
    function ali_send_msg($phone,$code,$temParam,$signname)
    {
        //print_r([$phone,$code,$temParam]);exit;
        AlibabaCloud::accessKeyClient('LTAI4G34bAd3brYZdWpLS6JD', 'fVTgRJK4vIoQgcpZWImhaUnsj91VM0')
            ->regionId('cn-hangzhou')
            ->asDefaultClient();

        try
        {
            $result = AlibabaCloud::rpc()
                ->product('Dysmsapi')
                // ->scheme('https') // https | http
                ->version('2017-05-25')
                ->action('SendSms')
                ->method('POST')
                ->host('dysmsapi.aliyuncs.com')
                ->options(['query' =>
                    [
                        'RegionId' => "default",
                        'PhoneNumbers' => $phone,
                        'SignName' => $signname,
                        'TemplateCode' => $code,
                        'TemplateParam' => json_encode($temParam)
                    ],])
                ->request();
            // print_r($result->toArray());
        }catch(ClientException $e) {
            return $e->getErrorMessage() . PHP_EOL;
        } catch (ServerException $e) {
            return $e->getErrorMessage() . PHP_EOL;
        }
        return '成功';
    }
}

if(!function_exists('test_write_file')){
    function test_write_file($file){
        $fp    = @fopen($file, "r+");
        if (!$fp) {
            return false;
        }else{
            fclose($fp);
            return true;
        }
    }
}

if (!function_exists('test_write_dir')) {
    function test_write_dir($dir)
    {
        $tfile = "_test.txt";
        $fp    = @fopen($dir . "/" . $tfile, "w");
        if (!$fp) {
            return false;
        }
        fclose($fp);
        $rs = @unlink($dir . "/" . $tfile);
        if ($rs) {
            return true;
        }
        return false;
    }
}

/**
 * 获取url绝对跟路径
 */
if (!function_exists('get_request_absroot')) {
    function get_request_absroot() {
        $absroot = request()->root(true);
        return (substr($absroot, -10) != '/index.php' ? $absroot : substr($absroot, 0, -10)) . '/';
    }
}



/**
 * 判断浏览器名称和版本
 */
function userBrowser() {
    $user_OSagent = $_SERVER['HTTP_USER_AGENT'];

    if (strpos($user_OSagent, "Maxthon") && strpos($user_OSagent, "MSIE")) {
        $visitor_browser = "Maxthon(Microsoft IE)";
    } elseif (strpos($user_OSagent, "Maxthon 2.0")) {
        $visitor_browser = "Maxthon 2.0";
    } elseif (strpos($user_OSagent, "Maxthon")) {
        $visitor_browser = "Maxthon";
    } elseif (strpos($user_OSagent, "MSIE 9.0")) {
        $visitor_browser = "MSIE 9.0";
    } elseif (strpos($user_OSagent, "MSIE 8.0")) {
        $visitor_browser = "MSIE 8.0";
    } elseif (strpos($user_OSagent, "MSIE 7.0")) {
        $visitor_browser = "MSIE 7.0";
    } elseif (strpos($user_OSagent, "MSIE 6.0")) {
        $visitor_browser = "MSIE 6.0";
    } elseif (strpos($user_OSagent, "MSIE 5.5")) {
        $visitor_browser = "MSIE 5.5";
    } elseif (strpos($user_OSagent, "MSIE 5.0")) {
        $visitor_browser = "MSIE 5.0";
    } elseif (strpos($user_OSagent, "MSIE 4.01")) {
        $visitor_browser = "MSIE 4.01";
    } elseif (strpos($user_OSagent, "MSIE")) {
        $visitor_browser = "MSIE 较高版本";
    } elseif (strpos($user_OSagent, "NetCaptor")) {
        $visitor_browser = "NetCaptor";
    } elseif (strpos($user_OSagent, "Netscape")) {
        $visitor_browser = "Netscape";
    } elseif (strpos($user_OSagent, "Chrome")) {
        $visitor_browser = "Chrome";
    } elseif (strpos($user_OSagent, "Lynx")) {
        $visitor_browser = "Lynx";
    } elseif (strpos($user_OSagent, "Opera")) {
        $visitor_browser = "Opera";
    } elseif (strpos($user_OSagent, "Konqueror")) {
        $visitor_browser = "Konqueror";
    } elseif (strpos($user_OSagent, "Mozilla/5.0")) {
        $visitor_browser = "Mozilla";
    } elseif (strpos($user_OSagent, "Firefox")) {
        $visitor_browser = "Firefox";
    } elseif (strpos($user_OSagent, "U")) {
        $visitor_browser = "Firefox";
    } else {
        $visitor_browser = "其它";
    }
    return $visitor_browser;
}
function validate($data,$rule){
    foreach ($rule as $k=>$v){
        if(is_string($v)){
            if(!isset($data[$v]) || empty($data[$v])){
                return true;
            }
        }
    }
    return false;
}
function fh($code, $status, $message, $data)
{
    return json_encode([
        'code' => $code,
        'status' => $status,
        'message' => $message,
        'data' => $data
    ], JSON_UNESCAPED_UNICODE);
}
function is_msg($data,$key,$msg = '参数缺失')
{
    if(!isset($data[$key]))die(msgerror($msg)->getContent());
}
//外部接口报错返回
function msgerror($msg = '操作失败', $data = [])
{
    return fh(404, 'error', $msg, $data);
}
//外部接口成功返回
function datasuccess($data = [], $msg = '操作成功')
{
    return fh(200, 'success', $msg, $data);
}
//内部接口报错返回
function msg($msg = '请求错误')
{
    return ['status'=>'error','msg'=>$msg];
}
function param($request)
{
    return array_filter($request->all());
}
function layui($data, $count)
{
    return json_encode([
        'code' => 0,
        'msg' => '',
        'count' => $count,
        'data' => $data
    ], JSON_UNESCAPED_UNICODE);
}

function b_str($arr, $i = ',')
{
    return implode($i, $arr);
}

function b_arr($str, $i = ',')
{
    return explode($i, $str);
}
//后台侧边栏目录层级
function select_getTree($all_cate, $cate_pid = 0, $cate_lev = 1,&$cate_tree =[]){
    foreach ($all_cate as $k => $v) {
        if ($v['parent_id'] == $cate_pid) {
            $all_cate[$k]['level'] = $cate_lev;
            $cate_tree[] = $all_cate[$k];
            select_getTree($all_cate, $v['id'], $cate_lev + 1,$cate_tree);
        }
    }
    return $cate_tree;
}

/**
 *
 * 打印调试
 */
if(!function_exists('pr')){
    function pr($var){
        if(is_object($var)||is_array($var))
        {
            echo '<pre>';
            print_r($var);
            echo '</pre>';
        }else{
            echo $var .PHP_EOL;
        }
    }
}
/**
 *
 * 打印调试
 */
if(!function_exists('v')){
    function v($var){
        echo '<pre>';
        var_dump($var);
        echo '</pre>';
    }
}
/**
 * 字符串命名风格转换
 * type 0 将Java风格转换为C的风格 1 将C风格转换为Java的风格
 * @param string  $name 字符串
 * @param integer $type 转换类型
 * @param bool    $ucfirst 首字母是否大写（驼峰规则）
 * @return string
 */
if (!function_exists('parse_name')) {
    function parse_name($name, $type = 0, $ucfirst = true)
    {
        if ($type) {
            $name = preg_replace_callback('/_([a-zA-Z])/', function ($match) {
                return strtoupper($match[1]);
            }, $name);

            return $ucfirst ? ucfirst($name) : lcfirst($name);
        } else {
            return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_"));
        }
    }
}
/**
 * 二维数组排序
 * $array   要处理的数据
 * $keys    排序依据字段
 * $sort    排序方式，默认顺序
 * */
function arraySort($array, $keys, $sort = SORT_ASC) {
    $keysValue = [];
    foreach ($array as $k => $v) {
        $keysValue[$k] = $v[$keys];
    }
    array_multisort($keysValue, $sort, $array);
    return $array;
}
/**
 * 计算2点之间直线距，
 *
 * @param array  $lat1    目的地纬度
 * @param string $lng1    目的地经度
 * @param array  $lat2    当前位置地纬度
 * @param array  $lng2    当前位置地经度
 */
function GetDistance($lat1, $lng1, $lat2, $lng2, $len_type = 1, $decimal = 2)
{
    $radLat1 = (string)$lat1 * PI ()/ 180.0;   //PI()圆周率
    $radLat2 = (string)$lat2 * PI() / 180.0;
    $a = $radLat1 - $radLat2;
    $b = ($lng1 * PI() / 180.0) - ((string)$lng2 * PI() / 180.0);
    $s = 2 * asin(sqrt(pow(sin($a/2),2) + cos($radLat1) * cos($radLat2) * pow(sin($b/2),2)));
    $s = $s * 6378.137;
    $s = round($s * 1000);
    if ($len_type == 1)
    {
        $s *= 1000;
    }
    return round($s, $decimal);
}
/**
 * 无限级
 * 后端权限树
 * $data array          栏目数据2维
 * $pId  string|number  上级ID
 */
if (!function_exists('au_getTree')) {
    function au_getTree($data, $pId,$key = 'pid',$value = 'p_menu')
    {
        $tree = [];
        foreach ($data as $k => $v) {
            if ($v[$key] == $pId) {
                unset($v['checked']);
                $v[$value] = getTree($data, $v['id'],$key,$value);
//                if(!empty($v[$value])){
//                }
                $tree[] = $v;

            }
        }
        return $tree;
    }
}
/**
 * 无限级
 * 后端栏目
 * $data array          栏目数据2维
 * $pId  string|number  上级ID
 */
if (!function_exists('getTree')) {
    function getTree($data, $pId,$key = 'parent_id',$value = 'p_menu')
    {
        $tree = [];
        foreach ($data as $k => $v) {
            if ($v[$key] == $pId) {
                $v[$value] = getTree($data, $v['id'],$key,$value);
                $tree[] = $v;
            }
        }
        return $tree;
    }
}
/**
 * 无限级
 * 无限极最高级直属
 * $user array          用户数据
 * $pid  string|number  上级ID
 */
if(!function_exists('pap')){
    function pap($user,$pid = 0){
        if($user['parent_id'] != 0){
            $parmen = app\admin\model\User::where('id','=',$user['parent_id'])->find();
            if($parmen){
                $parmen = $parmen->toArray();
                return pap($parmen, $parmen['parent_id']);
            }
        }
        return $user;
    }
}
/**
 * 无限级
 * 获取所有下级id
 */
if(!function_exists('getTeam')){
    function getTeam($teamId,$tIds=[]){
        if(!empty($teamId)){
            $uidArray = [];
            foreach ($teamId AS $item){
                $array = model('company')->where('pid',$item)->column('id');
                if(empty($array)){
                    continue;
                }
                $uidArray = array_merge($uidArray,$array);
            }
            $tIds = array_merge($tIds,$teamId,$uidArray);

            if(!empty($uidArray)){
                return getTeam($uidArray,$tIds);
            }

            return array_unique($tIds);
        }
        return $teamId;
    }
}

/**
 * 生成推广二维码（绑定关系）
 * send http request
 * @param  string|number  $id   所属用户ID
 * @param  string         $url  跳转url地址
 */
if(!function_exists('ewm')){
    function ewm($id,$url){
        $url = $url . $id;
//      $url = "{:url('api/user/useradd')}" . "?user_id=" . $id;
        include $_SERVER['DOCUMENT_ROOT'] . "/phpqrcode/phpqrcode.php"; //引入PHP QR库文件
        //保存地址
        $time = date('YmdHis') . rand(10000,99999);
        $imgname = '\upload\\userewm\\' . $time . '.jpg';
        $address = $_SERVER['DOCUMENT_ROOT'] . $imgname;
        //控制二维码容错率，不同的参数表示二维码可被覆盖的区域百分比
        $errorCorrectionLevel = "L";
        //控制生成图片的大小
        $matrixPointSize = "5";
        $margin = '5';
        //数据绑定到用户下
        model('user')->save(['ewmimages'=>$imgname],['id'=>$id]);
        $a = \QRcode::png($url, $address, $errorCorrectionLevel, $matrixPointSize,$margin);
        return true;
    }
}

/**
 * send http request
 * @param array $rq http请求信息
 *                   url        : 请求的url地址
 *                   method     : 请求方法，'get', 'post', 'put', 'delete', 'head'
 *                   data       : 请求数据，如有设置，则method为post
 *                   header     : 需要设置的http头部
 *                   host       : 请求头部host
 *                   timeout    : 请求超时时间
 *                   cert       : ca文件路径
 *                   ssl_version: SSL版本号
 * @return string    http请求响应
 */
if (!function_exists('curl_send')) {
    function curl_send($rq)
    {
        $curlHandle = curl_init();
        curl_setopt($curlHandle, CURLOPT_URL, $rq['url']);
        switch (true) {
            case isset($rq['method']) && in_array(strtolower($rq['method']), array('get', 'post', 'put', 'delete', 'head')):
                $method = strtoupper($rq['method']);
                break;
            case isset($rq['data']):
                $method = 'POST';
                break;
            default:
                $method = 'GET';
        }
        $header = isset($rq['header']) ? $rq['header'] : array();
        $header[] = 'Method:' . $method;

        $header[] = "User-Agent:Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.04506; .NET CLR 3.5.21022; .NET CLR 1.0.3705; .NET CLR 1.1.4322)";
        isset($rq['host']) && $header[] = 'Host:' . $rq['host'];
        curl_setopt($curlHandle, CURLOPT_HTTPHEADER, $header);
        curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curlHandle, CURLOPT_CUSTOMREQUEST, $method);
        isset($rq['timeout']) && curl_setopt($curlHandle, CURLOPT_TIMEOUT, $rq['timeout']);
        isset($rq['data']) && in_array($method, array('POST', 'PUT')) && curl_setopt($curlHandle, CURLOPT_POSTFIELDS, $rq['data']);

        $ssl = substr($rq['url'], 0, 8) == "https://" ? true : false;
        if (isset($rq['cert'])) {
            curl_setopt($curlHandle, CURLOPT_SSL_VERIFYPEER, true);
            curl_setopt($curlHandle, CURLOPT_CAINFO, $rq['cert']);
            curl_setopt($curlHandle, CURLOPT_SSL_VERIFYHOST, 2);
            if (isset($rq['ssl_version'])) {
                curl_setopt($curlHandle, CURLOPT_SSLVERSION, $rq['ssl_version']);
            } else {
                curl_setopt($curlHandle, CURLOPT_SSLVERSION, 4);
            }
        } else if ($ssl) {
            curl_setopt($curlHandle, CURLOPT_SSL_VERIFYPEER, false);   //true any ca
            curl_setopt($curlHandle, CURLOPT_SSL_VERIFYHOST, 2);       //check only host
            if (isset($rq['ssl_version'])) {
                curl_setopt($curlHandle, CURLOPT_SSLVERSION, $rq['ssl_version']);
            } else {
                curl_setopt($curlHandle, CURLOPT_SSLVERSION, 4);
            }
        }
        $return['content'] = curl_exec($curlHandle);
        $return['result'] = curl_getinfo($curlHandle);
        curl_close($curlHandle);
        return $return;
    }
}

if(!function_exists("curl_ikc")){

    function curl_ikc($rq){
        $query = new App\model\api\Setting();
        $ikucun_url =$query->where('var', 'ikucun_url')->value('value');
        $url = $rq['url'];
        $comps = explode(' ', microtime());
        $millis_time = sprintf('%d%03d', $comps[1], $comps[0] * 1000);
        $data = [];
        $param = $rq['params'];

        foreach ($param as $key => $val) {
            $data[$key] = $val;
        }

        $appsecret = $query->where('var', 'aikucun_appsecret')->value('value');
        $appkey = $query->where('var', 'aikucun_appkey')->value('value');
        $data['appKey'] = $appkey;
        $data['timestamp'] = intval($millis_time);
        $data['version'] = '1.0';
        ksort($data);

        $parameter = json_encode($data, 320) . $appsecret;
        $base_parameter = md5(base64_encode($parameter), true);
        $data['sign'] = strtoupper(bin2hex($base_parameter));

        $postData = json_encode($data);
        $result = curl_send([
            'url' => $ikucun_url.$url,
            'method' => 'POST',
            'header' => ['Content-Type: application/json'],
            'data' => $postData
        ]);
        $content = $result['content'];
        $response = json_decode($content, true);
        Log::channel('vip')->info('[COMMON ICK REQUEST]', ['url' => $url, 'params' => $postData, 'response' => $response['resultCode'] ?? $response]);
        if($response){
            if ($response['resultCode'] == 999999) {
//            Log::info('[ikucunSuccess]', $response );
                return ['status'=>true,'response'=>$response['data']];
            } else {
                Log::info('[ikucunError]', $response);
                return ['status'=>false,'response'=>$response, 'params' => $rq];
            }
        }
        return ['status'=>false,'response'=>$response];
    }
}

/**
 * 随机字符
 * @param int $length 长度
 * @param string $type 类型
 * @param int $convert 转换大小写 1大写 0小写
 * @return string
 * @author rainfer <1055213284@qq.com>
 */
function random($length = 6, $type = 'number', $convert = 0)
{

    $config = array(
        'number' => '1234567890',
        'letter' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
        'string' => 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789',
        'all' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
    );
    if (!isset($config[$type])) $type = 'number';
    $string = $config[$type];

    $code = '';
    $strlen = strlen($string) - 1;
    for ($i = 0; $i < $length; $i++) {
        $code .= $string[mt_rand(0, $strlen)];
    }
    if (!empty($convert)) {
        $code = ($convert > 0) ? strtoupper($code) : strtolower($code);
    }
    return $code;
}
/**
 * 文件上传
 * $file_info       上传的文件对象
 * $folder          保存图片地址
 * $filename        新生成的文件名称，默认为随机生成
 * $forbidden_ext   允许上传的文件格式
 */
if (!function_exists('upload_file')) {
    function upload_file($file_info, $size = 1024 * 1024 * 30, $folder = 'file_up', $filename = null, $forbidden_ext = ['jpg','jpeg','png','img'])
    {
        $GLOBALS['upload_file_error'] = '';
        switch ($file_info['error']) {
            case '0':
                break;
            case '1':
                $GLOBALS['upload_file_error'] = '文件大小超过了php.ini定义的upload_max_filesize值';
                break;
            case '2':
                $GLOBALS['bbot_upload_file_error'] = '文件大小超过了HTML定义的MAX_FILE_SIZE值';
                break;
            case '3':
                $GLOBALS['upload_file_error'] = '文件上传不完全';
                break;
            case '4':
                $GLOBALS['upload_file_error'] = '无文件上传';
                break;
            case '6':
                $GLOBALS['upload_file_error'] = '缺少临时文件夹';
                break;
            case '7':
                $GLOBALS['upload_file_error'] = '写文件失败';
                break;
            case '8':
                $GLOBALS['upload_file_error'] = '上传被其它扩展中断';
                break;
            case '':
                $GLOBALS['upload_file_error'] = '上传表单错误';
                break;
            case '999':
            default:
                $GLOBALS['upload_file_error'] = '未知错误';
        }
        if (!empty($GLOBALS['upload_file_error'])) {
            return false;
        }
        if (!is_uploaded_file($file_info['tmp_name'])) {
            if (!empty($GLOBALS['last_upload'])) {
                $GLOBALS['last_upload'] = null;
                return $GLOBALS['last_upload'];
            } else {
                $GLOBALS['upload_file_error'] = '不是上传文件';
                return false;
            }
        }
        if ($file_info['size'] > $size) {
            $GLOBALS['upload_file_error'] = '文件超过规定大小';
            return false;
        }
        $ext = explode('.', $file_info['name']);
        $arr['size'] = $file_info['size'];
        $arr['name'] = $ext[0];
        $ext = strtolower(array_pop($ext));
        $arr['ext'] = $ext;
        if (!in_array($ext, $forbidden_ext)) {
            $GLOBALS['upload_file_error'] = "不允许上传后缀名为[$ext]的文件";
            return false;
        }
        $basepath = $_SERVER['DOCUMENT_ROOT'] . '/upload';
        if (!file_exists($basepath)) {
            mkdir($basepath, 0777);
        }
        $basepath = $basepath . '/' . $folder . '/';
        if (!file_exists($basepath)) {
            mkdir($basepath, 0777);
        }
        $basepath = $basepath . date('Ym');
        if (!file_exists($basepath)) {
            mkdir($basepath, 0777);
        }
        if (empty($filename)) {
            $filename = uniqid(mt_rand()) . '.' . $ext;
        } else {
            $filename = $filename . '.' . $ext;
        }
        move_uploaded_file($file_info['tmp_name'], $basepath . '/' . $filename);
        $GLOBALS['last_upload'] = '/upload/' . $folder . '/' . date('Ym') . '/' . $filename;
        $arr['file'] = $GLOBALS['last_upload'];
        return $arr;
    }
}

use App\model\api\Setting;
use Illuminate\Support\Facades\Log;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Reader\Xls;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use PhpOffice\PhpSpreadsheet\Style\Color;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;

/**
 * Excel导出，TODO 可继续优化
 *
 * @param array $datas 导出数据，格式['A1' => 'XXXX公司报表', 'B1' => '序号']
 * @param string $fileName 导出文件名称
 * @param array $options 操作选项，例如：
 *                           bool   print       设置打印格式
 *                           string freezePane  锁定行数，例如表头为第一行，则锁定表头输入A2
 *                           array  setARGB     设置背景色，例如['A1', 'C1']
 *                           array  setWidth    设置宽度，例如['A' => 30, 'C' => 20]
 *                           bool   setBorder   设置单元格边框
 *                           array  mergeCells  设置合并单元格，例如['A1:J1' => 'A1:J1']
 *                           array  formula     设置公式，例如['F2' => '=IF(D2>0,E42/D2,0)']
 *                           array  format      设置格式，整列设置，例如['A' => 'General']
 *                           array  alignCenter 设置居中样式，例如['A1', 'A2']
 *                           array  bold        设置加粗样式，例如['A1', 'A2']
 *                           string savePath    保存路径，设置后则文件保存到服务器，不通过浏览器下载
 */
function exportExcel($datas, $fileName = '', $options = [])
{
    try {
        if (empty($datas)) {
            return false;
        }
        //return 123;
        set_time_limit(0);
        /** @var Spreadsheet $objSpreadsheet */
//        $objSpreadsheet = app(Spreadsheet::class);
        $objSpreadsheet = new Spreadsheet();
        //return pr($objSpreadsheet);
        /* 设置默认文字居左，上下居中 */
        $styleArray = [
            'alignment' => [
                'horizontal' => Alignment::HORIZONTAL_LEFT,
                'vertical' => Alignment::VERTICAL_CENTER,
            ],
        ];
        $objSpreadsheet->getDefaultStyle()->applyFromArray($styleArray);
        /* 设置Excel Sheet */
        $activeSheet = $objSpreadsheet->setActiveSheetIndex(0);

        /* 打印设置 */
        if (isset($options['print']) && $options['print']) {
            /* 设置打印为A4效果 */
            $activeSheet->getPageSetup()->setPaperSize(PageSetup:: PAPERSIZE_A4);
            /* 设置打印时边距 */
            $pValue = 1 / 2.54;
            $activeSheet->getPageMargins()->setTop($pValue / 2);
            $activeSheet->getPageMargins()->setBottom($pValue * 2);
            $activeSheet->getPageMargins()->setLeft($pValue / 2);
            $activeSheet->getPageMargins()->setRight($pValue / 2);
        }

        /* 行数据处理 */
        foreach ($datas as $sKey => $sItem) {
            /* 默认文本格式 */
            $pDataType = DataType::TYPE_STRING;

            /* 设置单元格格式 */
            if (isset($options['format']) && !empty($options['format'])) {
                $colRow = Coordinate::coordinateFromString($sKey);

                /* 存在该列格式并且有特殊格式 */
                if (isset($options['format'][$colRow[0]]) &&
                    NumberFormat::FORMAT_GENERAL != $options['format'][$colRow[0]]) {
                    $activeSheet->getStyle($sKey)->getNumberFormat()
                        ->setFormatCode($options['format'][$colRow[0]]);

                    if (false !== strpos($options['format'][$colRow[0]], '0.00') &&
                        is_numeric(str_replace(['￥', ','], '', $sItem))) {
                        /* 数字格式转换为数字单元格 */
                        $pDataType = DataType::TYPE_NUMERIC;
                        $sItem = str_replace(['￥', ','], '', $sItem);
                    }
                } elseif (is_int($sItem)) {
                    $pDataType = DataType::TYPE_NUMERIC;
                }
            }

            $activeSheet->setCellValueExplicit($sKey, $sItem, $pDataType);

            /* 存在:形式的合并行列，列入A1:B2，则对应合并 */
            if (false !== strstr($sKey, ":")) {
                $options['mergeCells'][$sKey] = $sKey;
            }
        }

        unset($datas);

        /* 设置锁定行 */
        if (isset($options['freezePane']) && !empty($options['freezePane'])) {
            $activeSheet->freezePane($options['freezePane']);
            unset($options['freezePane']);
        }

        /* 设置宽度 */
        if (isset($options['setWidth']) && !empty($options['setWidth'])) {
            foreach ($options['setWidth'] as $swKey => $swItem) {
                $activeSheet->getColumnDimension($swKey)->setWidth($swItem);
            }

            unset($options['setWidth']);
        }

        /* 设置背景色 */
        if (isset($options['setARGB']) && !empty($options['setARGB'])) {
            foreach ($options['setARGB'] as $sItem) {
                $activeSheet->getStyle($sItem)
                    ->getFill()->setFillType(Fill::FILL_SOLID)
                    ->getStartColor()->setARGB(Color::COLOR_YELLOW);
            }

            unset($options['setARGB']);
        }

        /* 设置公式 */
        if (isset($options['formula']) && !empty($options['formula'])) {
            foreach ($options['formula'] as $fKey => $fItem) {
                $activeSheet->setCellValue($fKey, $fItem);
            }

            unset($options['formula']);
        }

        /* 合并行列处理 */
        if (isset($options['mergeCells']) && !empty($options['mergeCells'])) {
            $activeSheet->setMergeCells($options['mergeCells']);
            unset($options['mergeCells']);
        }

        /* 设置居中 */
        if (isset($options['alignCenter']) && !empty($options['alignCenter'])) {
            $styleArray = [
                'alignment' => [
                    'horizontal' => Alignment::HORIZONTAL_CENTER,
                    'vertical' => Alignment::VERTICAL_CENTER,
                ],
            ];

            foreach ($options['alignCenter'] as $acItem) {
                $activeSheet->getStyle($acItem)->applyFromArray($styleArray);
            }

            unset($options['alignCenter']);
        }

        /* 设置加粗 */
        if (isset($options['bold']) && !empty($options['bold'])) {
            foreach ($options['bold'] as $bItem) {
                $activeSheet->getStyle($bItem)->getFont()->setBold(true);
            }

            unset($options['bold']);
        }

        /* 设置单元格边框，整个表格设置即可，必须在数据填充后才可以获取到最大行列 */
        if (isset($options['setBorder']) && $options['setBorder']) {
            $border = [
                'borders' => [
                    'allBorders' => [
                        'borderStyle' => Border::BORDER_THIN, // 设置border样式
                        'color' => ['argb' => 'FF000000'], // 设置border颜色
                    ],
                ],
            ];
            $setBorder = 'A1:' . $activeSheet->getHighestColumn() . $activeSheet->getHighestRow();
            $activeSheet->getStyle($setBorder)->applyFromArray($border);
            unset($options['setBorder']);
        }

        $fileName = !empty($fileName) ? $fileName : (date('YmdHis') . '.xlsx');

        if (!isset($options['savePath'])) {
            /* 直接导出Excel，无需保存到本地，输出07Excel文件 */
            header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
            header(
                "Content-Disposition:attachment;filename=" . iconv(
                    "utf-8", "GB2312//TRANSLIT", $fileName
                )
            );
            header('Cache-Control: max-age=0');//禁止缓存
            $savePath = 'php://output';
        } else {
            $savePath = $options['savePath'];
        }
        ob_clean();
        ob_start();
        $objWriter = IOFactory::createWriter($objSpreadsheet, 'Xlsx');
        $pp = $objWriter->save($savePath);
        /* 释放内存 */
        $objSpreadsheet->disconnectWorksheets();
        unset($objSpreadsheet);
        ob_end_flush();
        return true;
    } catch (Exception $e) {
        return $e->getMessage();
    }
}
/**
 * 微信小程序获取token
 * @param string $appid APPID
 * @param string $appsecret APP密钥
 * 需要引用缓存类文件
 */
if(!function_exists('wxtoken')) {
    function wxtoken($appid, $appsecret)
    {
        if (!Cache::get('token') || !Cache::get('time') && Cache::get('time') < time()) {
            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$appsecret";
            $curl = curl_send(['url' => $url]);
            if (isset(json_decode($curl['content'])->errcode)) {
                return ['code' => json_decode($curl['content'])->errcode, 'errmsg' => json_decode($curl['content'])->errmsg];
            }
            $token = json_decode($curl['content'])->access_token;
            Cache::set('token', $token);
            Cache::set('time', time() + 7200);
        } else {
            $token = Cache::get('token');
        }
        return $token;
    }
}
//清空文件夹函数和清空文件夹后删除空文件夹函数的处理
if(!function_exists('deldir')){
    function deldir($path){
        //如果是目录则继续
        if(is_dir($path)){
            //扫描一个文件夹内的所有文件夹和文件并返回数组
            $p = scandir($path);
            foreach($p as $val){
                //排除目录中的.和..
                if($val !="." && $val !=".."){
                    //如果是目录则递归子目录，继续操作
                    if(is_dir($path.$val)){
                        //子目录中操作删除文件夹和文件
                        deldir($path.$val.'/');
                        //目录清空后删除空文件夹
                        @rmdir($path.$val.'/');
                    }else{
                        //如果是文件直接删除
                        unlink($path.$val);
                    }
                }
            }
        }
    }
}
if(!function_exists('jm')){
    function jm($password){
        return md5(md5($password).'YSH'.base64_encode(724));
    }
}



/*************************
 *
 *      安装使用函数
 *
 *************************/
/**
 * 判断是否有安装记录
 */
if (!function_exists('is_ysh_installed')) {
    function is_ysh_installed() {
        static $isWooInstalled;
        if (empty($isWooInstalled)) {
            $isWooInstalled = file_exists(WWW. DS .'public' . DS . 'install.lock');
        }
        return $isWooInstalled;
    }
}
/**
 * 转换sql文件中字符串为标准样式
 */
if (!function_exists('get_file_sql')) {
    function get_file_sql($file, $tablePre, $charset = 'utf8', $defaultTablePre = 'ysh_', $defaultCharset = 'utf8mb4')
    {
        if (file_exists($file)) {
            $sql = file_get_contents($file);
            $sql = str_replace("\r", "\n", $sql);
            $sql = str_replace("BEGIN;\n", '', $sql);//兼容 navicat 导出的 insert 语句
            $sql = str_replace("COMMIT;\n", '', $sql);//兼容 navicat 导出的 insert 语句
            $sql = str_ireplace($defaultCharset, $charset, $sql);
            $sql = preg_replace('/AUTO_INCREMENT=\d{1,}/i', 'AUTO_INCREMENT=1', $sql);
            $sql = trim($sql);
            $sql  = str_replace(" `{$defaultTablePre}", " `{$tablePre}", $sql);
            $sqls = explode(";\n", $sql);
            return $sqls;
        }
        return [];
    }
}
/**
 * 执行sql语句添加数据
 */
if (!function_exists('execute_sql')) {
    function execute_sql($database, $sql)
    {
        $sql = trim($sql);
        preg_match('/CREATE TABLE .+ `([^ ]*)`/', $sql, $matches);
        if ($matches) {
            $table_name = $matches[1];
            $msg        = "创建数据表{$table_name}";

            try {

                $database->query($sql);
//                mysqli_query($database, $sql);
                return [
                    'error'   => 0,
                    'message' => $msg . ' 成功！'
                ];
            } catch (\Exception $e) {
                return [
                    'error'     => 1,
                    'message'   => $msg . ' 失败！',
                    'exception' => $e->getMessage()
                ];
            }

        } else {
            try {
                $database->query($sql);
//                mysqli_query($database, $sql);
                return [
                    'error'   => 0,
                    'message' => 'SQL执行成功!'
                ];
            } catch (\Exception $e) {
                return [
                    'error'     => 1,
                    'message'   => 'SQL执行失败！',
                    'exception' => $e->getMessage()
                ];
            }
        }
    }
}


/**
 * emoji转字符串
 * @param $str
 * @return string
 */
function emoji_encode($str)
{
    $strEncode = '';
    $length = mb_strlen($str, 'utf-8');
    for ($i = 0; $i < $length; $i++) {
        $_tmpStr = mb_substr($str, $i, 1, 'utf-8');
        if (strlen($_tmpStr) >= 4) {
            $strEncode .= '[[EMOJI:' . rawurlencode($_tmpStr) . ']]';
        } else {
            $strEncode .= $_tmpStr;
        }
    }
    return $strEncode;
}

/**
 * emoji字符串还原
 * @param $str
 * @return null|string|string[]
 */
function emoji_decode($str)
{
    $strDecode = preg_replace_callback('|\[\[EMOJI:(.*?)\]\]|', function ($matches) {
        return rawurldecode($matches[1]);
    }, $str);
    return $strDecode;
}

/**
 * 获取当前周期起止时间
 * @return array
 */
function get_current_week()
{
    $date = date("Y-m-d");  //当前日期
    $first = 1; //$first =1 表示每周星期一为开始时间 0表示每周日为开始时间
    $w = date("w", strtotime($date));  //获取当前周的第几天 周日是 0 周一 到周六是 1 -6
    $d = $w ? $w - $first : 6;  //如果是周日 -6天
    $now_start = date("Y-m-d", strtotime("$date -".$d." days")); //本周开始时间
    $now_end = date("Y-m-d", strtotime("$now_start +6 days"));  //本周结束时间
    return [$now_start. ' 00:00:00', $now_end.' 23:59:59'];
}

/**
 * 获取指定天数 起止时间
 * @return array
 */
function get_days_interval($days)
{
    $date_end = date("Y-m-d");  //当前日期
    $date_start = date("Y-m-d", strtotime("-".$days." days")); //本周开始时间
    return [$date_start. ' 00:00:00', $date_end.' 23:59:59'];
}

/**
 * 获取某年的天数
 * @return string|int
 */
function cal_days_in_year($year)
{
    $days = 0;
    for ($month = 1; $month <= 12; $month++) {
        $days = $days +date('t', mktime(0, 0, 0, $month, 1, $year));
    }
    return $days;
}

/**
 * 获取省份简称列表
 * @param string $fullProvince 省份全称
 * @return string
 */
function get_shot_province($fullProvince)
{
    $provinces = [
        '四川','山西','陕西','云南','青海','贵州','重庆','北京',
        '上海','天津','安徽','河北','河南','山东','江苏','浙江',
        '江西','福建','广东','广西','甘肃','宁夏','内蒙古','新疆',
        '西藏','吉林','辽宁','黑龙江','湖南','海南','湖北','台湾',
        '香港','澳门'
        ];
    $shortProvince = '';
    foreach ($provinces as $province){
        if(strpos($fullProvince, $province) !== false){
            $shortProvince = $province;
            break;
        }
    }
    return $shortProvince??$fullProvince;
}

